package com.jeesite.modules.auth.entity;

import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.jeesite.common.entity.DataEntity;
import com.jeesite.common.mybatis.annotation.Column;
import com.jeesite.common.mybatis.annotation.Table;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;

import java.io.Serial;
import java.util.Date;

/**
 * Authme 实体类（用户认证信息）
 * 映射 SQLite 数据库 authme 表，包含用户基础信息、登录状态、坐标等字段
 * @author Qx
 * @version 2025-08-28
 */
@Table(
		name = "authme",          // 数据库表名（与SQLite表完全一致）
		alias = "a",              // 表别名（用于复杂查询的表关联）
		label = "用户认证信息",    // 中文标签（用于前端显示或日志）
		columns = {
				// 主键映射：数据库 id → 实体 tid（解决字段名不一致问题）
				@Column(name = "id", attrName = "tid", label = "主键ID", isPK = true),
				// 用户名（非空，最长255字符）
				@Column(name = "username", attrName = "username", label = "用户名"),
				// 真实姓名（非空，最长255字符）
				@Column(name = "realname", attrName = "realname", label = "真实姓名"),
				// 密码（非空，最长255字符）
				@Column(name = "password", attrName = "password", label = "密码"),
				// 登录IP（最长40字符，支持IPv6）
				@Column(name = "ip", attrName = "ip", label = "登录IP"),
				// 最后登录时间（更新时强制更新此字段）
				@Column(name = "lastlogin", attrName = "lastlogin", label = "最后登录时间", isUpdateForce = true),
				// 注册IP（最长40字符）
				@Column(name = "regip", attrName = "regip", label = "注册IP"),
				// 注册时间
				@Column(name = "regdate", attrName = "regdate", label = "注册时间"),
				// 游戏坐标（x/y/z）
				@Column(name = "x", attrName = "x", label = "坐标X"),
				@Column(name = "y", attrName = "y", label = "坐标Y"),
				@Column(name = "z", attrName = "z", label = "坐标Z"),
				// 游戏世界（非空，最长255字符）
				@Column(name = "world", attrName = "world", label = "游戏世界"),
				// 游戏视角（偏航角/俯仰角，更新时强制更新）
				@Column(name = "yaw", attrName = "yaw", label = "偏航角", isUpdateForce = true),
				@Column(name = "pitch", attrName = "pitch", label = "俯仰角", isUpdateForce = true),
				// 邮箱（最长255字符）
				@Column(name = "email", attrName = "email", label = "邮箱"),
				// 登录状态（0=未登录，1=已登录）
				@Column(name = "islogged", attrName = "islogged", label = "登录状态"),
				// 会话状态（0=无会话，1=有会话）
				@Column(name = "hassession", attrName = "hassession", label = "会话状态"),
				// TOTP双因素认证密钥（最长32字符）
				@Column(name = "totp", attrName = "totp", label = "TOTP密钥")
		},
		orderBy = "a.id DESC"  // 默认排序：按主键降序（最新记录在前）
)
public class Authme extends DataEntity<Authme> {

	@Serial
	private static final long serialVersionUID = 1L;

	// ====================== 数据库表字段映射（与@Table.columns对应） ======================
	private Long tid;                // 主键ID（对应数据库id字段）
	private String username;         // 用户名
	private String realname;         // 真实姓名
	private String password;         // 密码（建议存储加密后的密文）
	private String ip;               // 登录IP
	private Date lastlogin;          // 最后登录时间
	private String regip;            // 注册IP
	private Date regdate;            // 注册时间
	private Double x;                // 游戏坐标X
	private Double y;                // 游戏坐标Y
	private Double z;                // 游戏坐标Z
	private String world;            // 游戏世界
	private Double yaw;              // 偏航角（水平旋转角度）
	private Double pitch;            // 俯仰角（垂直旋转角度）
	private String email;            // 邮箱
	private Integer islogged;        // 登录状态（0=未登录，1=已登录）
	private Integer hassession;      // 会话状态（0=无会话，1=有会话）
	private String totp;             // TOTP双因素认证密钥

	// ====================== 构造方法（默认+带主键） ======================
	public Authme() {
		this(null);  // 无参构造：默认创建"新记录"（isNewRecord=true）
	}

	public Authme(String id) {
		super(id);  // 带主键构造：根据id判断是否为新记录（id=null→新记录）
	}

	// ====================== Getter/Setter 方法（严格与字段对应，避免拼写错误） ======================
	// 主键tid：Long类型用ToStringSerializer序列化（避免前端长整数精度丢失）
	@JsonSerialize(using = ToStringSerializer.class)
	public Long getTid() {
		return tid;
	}

	public void setTid(Long tid) {
		this.tid = tid;
	}

	// 用户名：非空校验+长度限制（与数据库字段长度一致）
	@NotBlank(message = "用户名不能为空")
	@Size(min = 1, max = 255, message = "用户名长度必须在1-255个字符之间")  // 修正min=1（避免空字符串）
	public String getUsername() {
		return username;
	}

	public void setUsername(String username) {
		this.username = username;
	}

	// 真实姓名：非空校验+长度限制
	@NotBlank(message = "真实姓名不能为空")
	@Size(min = 1, max = 255, message = "真实姓名长度必须在1-255个字符之间")
	public String getRealname() {
		return realname;
	}

	public void setRealname(String realname) {
		this.realname = realname;
	}

	// 密码：非空校验+长度限制（存储加密后的密文，长度可能更长，建议max=512）
	@NotBlank(message = "密码不能为空")
	@Size(min = 8, max = 512, message = "密码长度必须在8-512个字符之间")  // 修正：密码最小8位更安全
	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}

	// 登录IP：长度限制（支持IPv6最长40字符）
	@Size(max = 40, message = "登录IP长度不能超过40个字符")
	public String getIp() {
		return ip;
	}

	public void setIp(String ip) {
		this.ip = ip;
	}

	// 最后登录时间：指定JSON序列化格式（前端统一显示"yyyy-MM-dd HH:mm"）
	@JsonFormat(pattern = "yyyy-MM-dd HH:mm", timezone = "GMT+8")  // 新增时区（避免跨时区偏差）
	public Date getLastlogin() {
		return lastlogin;
	}

	public void setLastlogin(Date lastlogin) {
		this.lastlogin = lastlogin;
	}

	// 注册IP：长度限制
	@Size(max = 40, message = "注册IP长度不能超过40个字符")
	public String getRegip() {
		return regip;
	}

	public void setRegip(String regip) {
		this.regip = regip;
	}

	// 注册时间：非空校验+JSON格式
	@NotNull(message = "注册时间不能为空")
	@JsonFormat(pattern = "yyyy-MM-dd HH:mm", timezone = "GMT+8")
	public Date getRegdate() {
		return regdate;
	}

	public void setRegdate(Date regdate) {
		this.regdate = regdate;
	}

	// 游戏坐标X：非空校验（游戏场景中坐标必填）
	@NotNull(message = "坐标X不能为空")
	public Double getX() {
		return x;
	}

	public void setX(Double x) {
		this.x = x;
	}

	// 游戏坐标Y：非空校验
	@NotNull(message = "坐标Y不能为空")
	public Double getY() {
		return y;
	}

	public void setY(Double y) {
		this.y = y;
	}

	// 游戏坐标Z：非空校验
	@NotNull(message = "坐标Z不能为空")
	public Double getZ() {
		return z;
	}

	public void setZ(Double z) {
		this.z = z;
	}

	// 游戏世界：非空校验+长度限制
	@NotBlank(message = "游戏世界不能为空")
	@Size(min = 1, max = 255, message = "游戏世界名称长度必须在1-255个字符之间")
	public String getWorld() {
		return world;
	}

	public void setWorld(String world) {
		this.world = world;
	}

	// 偏航角：允许为空（未设置时默认0）
	public Double getYaw() {
		return yaw;
	}

	public void setYaw(Double yaw) {
		this.yaw = yaw;
	}

	// 俯仰角：允许为空
	public Double getPitch() {
		return pitch;
	}

	public void setPitch(Double pitch) {
		this.pitch = pitch;
	}

	// 邮箱：长度限制（支持标准邮箱格式，可后续加@Pattern校验）
	@Size(max = 255, message = "邮箱长度不能超过255个字符")
	public String getEmail() {
		return email;
	}

	public void setEmail(String email) {
		this.email = email;
	}

	// 登录状态：非空校验（0=未登录，1=已登录，枚举更清晰，可后续优化为枚举类型）
	@NotNull(message = "登录状态不能为空")
	public Integer getIslogged() {
		return islogged;
	}

	public void setIslogged(Integer islogged) {
		this.islogged = islogged;
	}

	// 会话状态：非空校验（0=无会话，1=有会话）
	@NotNull(message = "会话状态不能为空")
	public Integer getHassession() {
		return hassession;
	}

	public void setHassession(Integer hassession) {
		this.hassession = hassession;
	}

	// TOTP密钥：长度限制（标准TOTP密钥32字符）
	@Size(max = 32, message = "TOTP密钥长度不能超过32个字符")
	public String getTotp() {
		return totp;
	}

	public void setTotp(String totp) {
		this.totp = totp;
	}
}